
/***************************************************************************
 *   boque 
 *                                                                         *
 *   Copyright (C) 2010 by kuerant                                         *
 *                         <kuerant@gmail.com>                             *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This library is distributed in the hope that it will be usefull, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
 *   Library General Public License for more details.                      *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston,                *
 *   MA 02111-1307, USA                                                    *
 ***************************************************************************/


#ifndef HTTP_SERVER3_CONNECTION_HPP
#define HTTP_SERVER3_CONNECTION_HPP

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>

#include "handler.hpp"


namespace boque {
namespace trasit {

/// Represents a single connection from a client.
class Connection
	: public boost::enable_shared_from_this<Connection>,
	private boost::noncopyable
{
public:
	/// Construct a connection with the given io_service.
	explicit Connection(boost::asio::io_service& io_service, Handler* handler_p, boost::mutex* handler_mutex_p);

	/// Get the socket associated with the connection.
	boost::asio::ip::tcp::socket& socket();

	/// Start the first asynchronous operation for the connection.
	void start();

private :
	void	waitRequest();

private:
	/// Handle completion of a read operation.
	void handle_read(const boost::system::error_code& e,
			std::size_t bytes_transferred);

	/// Handle completion of a write operation.
	void handle_write(const boost::system::error_code& e);

	/// Strand to ensure the connection's handlers are not called concurrently.
	boost::asio::io_service::strand strand_;

	/// Socket for the connection.
	boost::asio::ip::tcp::socket socket_;


	/// Buffer for incoming data.
	boost::array<char, 8192> buffer_;

	/// The incoming request.
	boost::asio::streambuf request_;


	/// The reply to be sent back to the client.
	boost::asio::streambuf reply_;

	/// service object
	Handler*	_handler_p;
	boost::mutex*	_handler_mutex_p;
};

typedef boost::shared_ptr<Connection> connection_ptr;

} // namespace trasit
} // namespace boque

#endif // HTTP_SERVER3_CONNECTION_HPP
